// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module net_arbi
(
    input  wire I_sclk,
    input  wire I_rst_n,
    //
    input  wire I_req_net_0,
    output reg  O_ack_net_0,
    input  wire I_req_net_1,
    output reg  O_ack_net_1,
    input  wire I_req_net_2,
    output reg  O_ack_net_2,
    input  wire I_req_net_3,
    output reg  O_ack_net_3,
    input  wire I_req_net_4,
    output reg  O_ack_net_4,
    //
    input  wire [ 7: 0]  I_reg_nop_bytes

);

/******************************************************************************
                                <localparams>
******************************************************************************/

localparam // state
    IDLE = 0,
    ACK_0 = 1,
    ACK_1 = 1<<1,
    ACK_2 = 1<<2,
    ACK_3 = 1<<3,
    ACK_4 = 1<<4,
    NOP = 1<<5;

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  [ 5: 0] state;
reg  [ 5: 0] next_state;
reg  [ 8: 0] nop_cnt;

/******************************************************************************
                                <module body>
******************************************************************************/
// state machine : state
always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        state <= IDLE;
    else
        state <= next_state;

always @(*)
    case (state)
        IDLE:
            if (I_req_net_0)
                next_state = ACK_0;
            else if (I_req_net_1)
                next_state = ACK_1;
            else if (I_req_net_2)
                next_state = ACK_2;
            else if (I_req_net_3)
                next_state = ACK_3;
            else if (I_req_net_4)
                next_state = ACK_4;
            else
                next_state = IDLE;
        ACK_0:
            if (!I_req_net_0)
                next_state = NOP;
            else
                next_state = ACK_0;
        ACK_1:
            if (!I_req_net_1)
                next_state = NOP;
            else
                next_state = ACK_1;
        ACK_2:
            if (!I_req_net_2)
                next_state = NOP;
            else
                next_state = ACK_2;
        ACK_3:
            if (!I_req_net_3)
                next_state = NOP;
            else
                next_state = ACK_3;
        ACK_4:
            if (!I_req_net_4)
                next_state = NOP;
            else
                next_state = ACK_4;
        NOP:
            if (nop_cnt > I_reg_nop_bytes)
                next_state = IDLE;
            else
                next_state = NOP;
        default:
            next_state = IDLE;
    endcase

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        nop_cnt <= 'd0;
    else if (state != NOP)
        nop_cnt <= 'd0;
    else
        nop_cnt <= nop_cnt + 1;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_ack_net_0 <= 1'b0;
    else
        O_ack_net_0 <= state == ACK_0;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_ack_net_1 <= 1'b0;
    else
        O_ack_net_1 <= state == ACK_1;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_ack_net_2 <= 1'b0;
    else
        O_ack_net_2 <= state == ACK_2;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_ack_net_3 <= 1'b0;
    else
        O_ack_net_3 <= state == ACK_3;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_ack_net_4 <= 1'b0;
    else
        O_ack_net_4 <= state == ACK_4;

endmodule
`default_nettype wire

